package com.cmcc.driver.ui.main


import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.location.Location
import android.location.LocationManager
import android.net.Uri
import android.os.Bundle
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.alibaba.android.arouter.launcher.ARouter
import com.cmcc.driver.R
import com.cmcc.driver.config.DriverPath
import com.cmcc.driver.data.entity.OrderDetail
import com.cmcc.driver.databinding.FragmentOrderProgressBinding
import com.cmcc.driver.ui.dialog.AppAlertDialog
import com.cmcc.driver.ui.dialog.AppInputDialog
import com.cmcc.driver.ui.dialog.AppInputDialog.OnInputListener
import com.cmcc.driver.ui.dialog.AppProgressDialog
import com.cmcc.driver.ui.main.viewmodel.OrderProgressViewModel
import com.cmcc.driver.util.LocationUtil
import com.cmcc.shared.utils.GPSConverterUtils
import com.cmcc.shared.utils.clickWithTrigger
import com.google.android.gms.location.*
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.*
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.maps.android.PolyUtil
import kotlinx.android.synthetic.main.layout_driver_operation.view.*
import java.util.*

/**
 * 出单界面（已废弃）
 * Author: jiangxin
 * Date: 2019/11/5
 * Description:
 */
class OrderProgressFragment : Fragment(), OnMapReadyCallback {

    private lateinit var binding: FragmentOrderProgressBinding
    private var viewModel: OrderProgressViewModel? = null
    private var order: OrderDetail? = null


    private var progressDialog: AppProgressDialog? = null
    private var timer: Timer? = null

    private lateinit var mMap: GoogleMap
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var locationRequest: LocationRequest
    private lateinit var locationCallback: LocationCallback
    private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>


    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
        isMapReady = true
        mMap.isMyLocationEnabled = true

        val appointLoc = LocationUtil.getInstance().getCurrentLoc()
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(appointLoc, 18f))

        drawRoutes(googleMap)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        progressDialog = AppProgressDialog(context!!)

        fusedLocationClient =
            LocationServices.getFusedLocationProviderClient(activity as DriverMainActivity)

        locationRequest = LocationRequest()
        locationRequest.interval =
            10 * 1000L //请求时间间隔
        locationRequest.fastestInterval =
            1500L//最快时间间隔
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult?) {
                if (locationResult == null) return
                handleLocation(locationResult.lastLocation)
            }
        }

    }


    @SuppressLint("SetTextI18n")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = FragmentOrderProgressBinding.inflate(inflater, container, false)

        bottomSheetBehavior = BottomSheetBehavior.from(binding.progress)

        viewModel = ViewModelProviders.of(this).get(OrderProgressViewModel::class.java)

        binding.rejectOrder.clickWithTrigger {
            AppAlertDialog(context!!).setContent(getString(R.string.reject_order_send_alert_dialog))
                .setNavigation(getString(R.string.cancel), null)
                .setPositive(getString(R.string.make_sure),
                    View.OnClickListener {
                        progressDialog?.show()
                        viewModel?.cancel(order?.id.toString())
                            ?.observe(this, Observer { response ->
                                progressDialog?.dismiss()
                                if (response.code==200) {
                                    Toast.makeText(
                                        this.activity,
                                        getString(R.string.reject_order_success),
                                        Toast.LENGTH_LONG
                                    ).show()
                                } else
                                {
                                    Toast.makeText(
                                        this.activity,
                                        response.msg,
                                        Toast.LENGTH_LONG
                                    ).show()
                                }
                            })
                    }).show()
        }

        binding.optionsLayout.nextTip1.clickWithTrigger {
            val orderStatus: Int? = order?.status ?: -1
            if (orderStatus != -1) {
                if (orderStatus == 6) {
                    stopTimer()
                    if (activity is DriverMainActivity) (activity as DriverMainActivity).currentPage(
                        R.id.order_record
                    )
                    updateUI()
                }

                if (orderStatus == 3) {
                    changeOrder(1, 0.0, 0.0, 0.00, 4)
                } else if (orderStatus == 4) {
                    if (binding.amount.text.toString().isNotEmpty()) {
                        changeOrder(0, 10.0, 10.0, binding.amount.text.toString().toDouble(), 5)
                        binding.amount.text = ""
                    } else {
                        AppAlertDialog(context!!).setContent(getString(R.string.plz_input_number))
                            .setNavigation("", null, false)
                            .setPositive(getString(R.string.make_sure),
                                View.OnClickListener {

                                }).show()
                    }
                } else {
                    changeOrder(0, 0.0, 0.0, 0.00, orderStatus!!.plus(1))
                }
            }
        }

        binding.amount.clickWithTrigger {
            AppInputDialog(context!!)
                .setOnInputListener("0.0", object : OnInputListener {
                    override fun onInput(text: String) {
                        binding.amount.text = text
                    }
                })
                .show()
        }


        binding.contactPass.clickWithTrigger {
            AppAlertDialog(context!!).setContent(getString(R.string.if_you_need_call))
                .setNavigation(getString(R.string.cancel), null)
                .setPositive(getString(R.string.make_sure),
                    View.OnClickListener {

                        val data = Uri.parse("tel:"+order?.passenger?.phone)
                        val intent = Intent(Intent.ACTION_DIAL, data)
                        startActivity(intent)
                    }).show()
        }

        binding.collapsingLayout.clickWithTrigger {
            when (bottomSheetBehavior.state) {
                BottomSheetBehavior.STATE_COLLAPSED -> {//收起状态
                    bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
                }
                BottomSheetBehavior.STATE_EXPANDED -> {//展开状态
                    bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
                }
            }
        }



        bottomSheetBehavior.setBottomSheetCallback(object :
            BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, newState: Int) {
                when (bottomSheetBehavior.state) {
                    BottomSheetBehavior.STATE_COLLAPSED -> {//收起状态
                        binding.collapsing.setBackgroundResource(R.drawable.ic_behavior_collapsed)
                    }
                    BottomSheetBehavior.STATE_EXPANDED -> {//展开状态
                        binding.collapsing.setBackgroundResource(R.drawable.ic_behavior_expanded)
                    }
                }
            }

            override fun onSlide(bottomSheet: View, slideOffset: Float) {}
        })

        viewModel?.orderDetail?.observe(this, Observer { order ->
            if (order == null) {
                this.order = null
                hasDrawDriverToStart = false
                hasDrawStartToEnd = false
                mMap.clear()
                binding.progress.visibility = View.GONE

                if (activity is DriverMainActivity)
                    (activity as DriverMainActivity).currentPage(R.id.order_receive)
            } else {
                this.order = order
                binding.progress.visibility = View.VISIBLE
                binding.directions.directionStart.text = order.startAddress
                binding.directions.directionEnd.text = order.endAddress

                binding.options.textView3.text =
                    getString(R.string.order_create_time, order.createTime)
                binding.options.tip.text =
                getString(R.string.order_tip) + (order.bountyFee?:"0.00")
                binding.options.tunnel.text =
                    getString(R.string.order_tunnel, order.tunnel?.name ?: getString(R.string.any))


                binding.options.remarks.text = getString(
                    R.string.order_remark,
                    if (order.remark.isNullOrEmpty()) getString(R.string.none) else order.remark
                )

                var stepTxt = ""
                when (order.status) {
                    1 -> {
                        stepTxt = getString(R.string.receive_passenger_and_now_start)
                        binding.rejectOrder.visibility = View.VISIBLE
                        binding.contactPass.visibility = View.VISIBLE
                        binding.feeInput.visibility = View.GONE
                    }
                    2 -> {
                        stepTxt = getString(R.string.arrived_destination)
                        binding.rejectOrder.visibility = View.GONE
                        binding.contactPass.visibility = View.GONE
                        binding.feeInput.visibility = View.GONE
                    }
                    3 -> {
                        stepTxt = getString(R.string.pay_under_line)
                        binding.rejectOrder.visibility = View.GONE
                        binding.contactPass.visibility = View.GONE
                        binding.feeInput.visibility = View.GONE
                    }
                    4 -> {
                        stepTxt = getString(R.string.comfirm_cash)
                        binding.rejectOrder.visibility = View.GONE
                        binding.contactPass.visibility = View.GONE
                        binding.feeInput.visibility = View.VISIBLE

                        binding.tipAddition.text =
                            "(+" + this.getString(R.string.order_tip) + (order.bountyFee?:"0.00") + ")"

                    }
                    5 -> {
                        stepTxt = getString(R.string.complete_trip)
                        binding.rejectOrder.visibility = View.GONE
                        binding.contactPass.visibility = View.GONE
                        binding.feeInput.visibility = View.GONE
                    }
                }

                binding.optionsLayout.nextTip1.text = stepTxt

            }
        })


        binding.navigation.clickWithTrigger {

            val currentLatLng: LatLng? = LocationUtil.getInstance().getCurrentLoc()

            if (null != currentLatLng) {
                val current = convert(currentLatLng)
                val startLatLng = LatLng(current.lat, current.lon)

                var endLatLng: LatLng? = null
                val status = order?.status
                if (status == 1) {
                    val endLat = order?.startCoordinates?.latitude ?: 0.0
                    val endLng = order?.startCoordinates?.longitude ?: 0.0
                    if (endLat != 0.0 && endLng != 0.0) {
                        val end = convert(LatLng(endLat, endLng))
                        endLatLng = LatLng(end.lat, end.lon)
                    }
                } else {
                    val endLat = order?.endCoordinates?.latitude ?: 0.0
                    val endLng = order?.endCoordinates?.longitude ?: 0.0
                    if (endLat != 0.0 && endLng != 0.0) {
                        val end = convert(LatLng(endLat, endLng))
                        endLatLng = LatLng(end.lat, end.lon)
                    }
                }
                if (null != endLatLng) {
                    ARouter.getInstance().build(DriverPath.NAVIGATION)
                        .withParcelable("start_point", startLatLng)
                        .withParcelable("end_point", endLatLng)
                        .navigation()
                }
            }
        }

        binding.locate.clickWithTrigger {
            requestLocationService()
        }


        updateUI()

        viewModel?.resMsg?.observe(this, Observer { resMsg ->
            progressDialog?.dismiss()
            if (null != resMsg) {
                if (resMsg.code == 200) {
                    updateUI()
                } else {
                    Toast.makeText(context, resMsg.msg, Toast.LENGTH_LONG).show()
                }
            } else {
                Toast.makeText(context, getString(R.string.operate_failed_retry), Toast.LENGTH_LONG)
                    .show()
            }
        })


        return binding.root
    }

    /**
     * 请求定位服务
     */
    private fun requestLocationService() {
        val locationManager =
            context!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            requestLocationUpdate()
        }
    }

    /**
     * 请求位置更新
     */
    private fun requestLocationUpdate() {
        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.myLooper()
        )
    }

    /**
     * 获取当前位置的回调方法
     */
    private fun handleLocation(lastLocation: Location) {
        val latLng = LatLng(lastLocation.latitude, lastLocation.longitude)
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18f))

        stopLocationUpdate()
    }

    private fun stopLocationUpdate() {
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    override fun onResume() {
        super.onResume()
        val mapFragment = childFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(this)

        startTimer()
    }

    override fun onPause() {
        super.onPause()

        stopTimer()
    }

    private fun startTimer() {
        timer = Timer()
        val task = object : TimerTask() {
            override fun run() {
                val currentLatLng = LocationUtil.getInstance().getCurrentLoc()
                if (null != currentLatLng) {
                    val startLat = order?.startCoordinates?.latitude ?: 0.0
                    val startLng = order?.startCoordinates?.longitude ?: 0.0
                    if (startLat != 0.0 && startLng != 0.0) {
                        val start = LatLng(startLat, startLng)
                        val status = order?.status
                        if (status == 1) {
                            drawDriverToStart(currentLatLng, start)
                        } else {
                            val endLat = order?.endCoordinates?.latitude ?: 0.0
                            val endLng = order?.endCoordinates?.longitude ?: 0.0

                            if (startLat != 0.0 && startLng != 0.0 && endLat != 0.0 && endLng != 0.0) {
                                val end = LatLng(endLat, endLng)
                                drawStartToEnd(start, end)
                            }
                        }
                    }

                    drawDriverLocation(currentLatLng)
                }
            }
        }
        timer?.schedule(task, 0, 5 * 1000L)
    }

    private fun stopTimer() {
        timer?.cancel()
        timer = null
    }

    private fun drawDriverToStart(driver: LatLng, start: LatLng) {
        if (!hasDrawDriverToStart) {//是否绘制过司机到起点的路线
            queryRoute(
                driver,
                start
            )

        }
    }

    private fun drawStartToEnd(start: LatLng, end: LatLng) {
        if (!hasDrawStartToEnd) {
            queryRoute(
                start,
                end
            )
        }
    }

    private var hasDrawDriverToStart = false
    private var hasDrawStartToEnd = false
    private var driverMarker: Marker? = null
    private var isMapReady = false

    private fun drawDriverLocation(latLng: LatLng) {
        if (isMapReady) {
            activity?.runOnUiThread {
                driverMarker?.remove()
                driverMarker = mMap.addMarker(
                    MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_car_red))
                )
            }
        }
    }

    private fun changeOrder(
        payMethod: Int, mileageFee: Double,
        durationFee: Double, totalAmount: Double, status: Int
    ) {
        if (!order?.id.isNullOrEmpty()) {
            progressDialog?.show()
            viewModel?.nextOrder(
                order?.id!!,
                payMethod,
                mileageFee,
                durationFee,
                totalAmount,
                status
            )
        }
    }


    fun updateUI() {
        viewModel?.queryOrderProgress()
    }

    /**
     * 请求路线
     */
    private fun queryRoute(
        startLatLng: LatLng,
        endLatLng: LatLng
    ) {
        viewModel?.getDirection(
            "${startLatLng.latitude},${startLatLng.longitude}",
            "${endLatLng.latitude},${endLatLng.longitude}"
        )
    }

    /**
     * 绘制路线到谷歌地图
     */
    private fun drawRoutes(map: GoogleMap) {
        viewModel?.direction?.observe(this, Observer {
            val decodedPath = PolyUtil.decode(it) //来源Google Map Util
            val lineOptions = PolylineOptions()
            lineOptions.addAll(decodedPath) //添加路线
            lineOptions.color(Color.parseColor("#0AC6A2")) //线条设置
            lineOptions.jointType(JointType.ROUND)
            lineOptions.width(15f)
            map.clear()
            map.addPolyline(lineOptions)
            val status = order?.status
            if (status == 1) {
                hasDrawDriverToStart = true
            } else {
                hasDrawStartToEnd = true
            }
            if (decodedPath.size > 2) {
                zoomRoute(map, decodedPath)

                map.addMarker(
                    MarkerOptions().position(decodedPath[0]).icon(
                        BitmapDescriptorFactory.fromResource(
                            R.drawable.ic_locate_current
                        )
                    )
                )

                map.addMarker(
                    MarkerOptions().position(decodedPath[decodedPath.size - 1]).icon(
                        if (order?.status == 1)
                            BitmapDescriptorFactory.fromResource(R.drawable.ic_start_point)
                        else
                            BitmapDescriptorFactory.fromResource(R.drawable.ic_end_point)
                    )
                )

                map.setOnCameraIdleListener { }
            }
        })
    }

    /**
     * Zooms a Route (given a List of LalLng) at the greatest possible zoom level.
     *
     * @param googleMap: instance of GoogleMap
     * @param lstLatLngRoute: list of LatLng forming Route
     */
    private fun zoomRoute(googleMap: GoogleMap?, lstLatLngRoute: List<LatLng>?) {

        if (googleMap == null || lstLatLngRoute == null || lstLatLngRoute.isEmpty()) {
            return
        }

        val boundsBuilder = LatLngBounds.Builder()
        for (latLngPoint in lstLatLngRoute)
            boundsBuilder.include(latLngPoint)

        val routePadding = 100
        val latLngBounds = boundsBuilder.build()

        googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, routePadding))
    }


//    fun openBaiduNavigation(toLatLng: LatLng, targetAddressName: String) {
//        val intent = Intent()
//        //导航界面
//        intent.setData(Uri.parse("baidumap://map/direction?destination=latlng:${toLatLng.latitude},${toLatLng.longitude}|name:${targetAddressName}&coord_type=bd09ll&mode=driving"))
//        //由于没获取到目的地地址，所以跳到目的地界面
//        //intent.setData(Uri.parse("baidumap://map/geocoder?location=${item?.la},${item?.lg}&src=andr.baidu.openAPIdemo"))
//        startActivity(intent)
//    }

    private fun openTencentNavigation(toLatLng: LatLng, targetAddressName: String) {
        val intent = Intent()
        val destination = convert(toLatLng)
        intent.setData(
            Uri.parse(
                "qqmap://map/routeplan?type=walk&to=${targetAddressName}&tocoord=${destination.lat},${destination.lon}&policy=1&referer=" + getString(
                    R.string.app_name
                )
            )
        )
        context?.startActivity(intent)
    }

    /**谷歌境外坐标系 (WGS-84) 转 火星坐标系(GCJ-02)的转换*/
    private fun convert(latlng: LatLng) =
        GPSConverterUtils.gps84_To_Gcj02(latlng.latitude, latlng.longitude)


}